package com.ruoyi.project.test.gds.formal;

import cn.hutool.core.io.FileUtil;
import com.ruoyi.project.test.gds.formal.GdsParameter;
import com.ruoyi.project.test.gds.formal.GdsParse;
import com.ruoyi.project.test.gds.formal.model.GdsDTO;
import com.ruoyi.project.test.gds.formal.model.GdsFile;
import com.ruoyi.project.test.gds.formal.model.GdsGraph;
import com.ruoyi.project.test.gds.formal.model.GdsStructure;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.math.BigInteger;

@Component
public class File2Hex {

    @Autowired
    public GdsParse gdsParse;

    public static void convertToHex(PrintStream out, File file) throws IOException {
        InputStream is = new FileInputStream(file);

        int bytesCounter =0;
        int value = 0;
        StringBuilder sbHex = new StringBuilder();
        StringBuilder sbText = new StringBuilder();
        StringBuilder sbResult = new StringBuilder();

        while ((value = is.read()) != -1) {
            //convert to hex value with "X" formatter
            sbHex.append(String.format("%02X ", value));

            //If the chracater is not convertable, just print a dot symbol "."
            if (!Character.isISOControl(value)) {
                sbText.append((char)value);
            }else {
                sbText.append(".");
            }

            //if 16 bytes are read, reset the counter,
            //clear the StringBuilder for formatting purpose only.
            if(bytesCounter==15){
                sbResult.append(sbHex).append("      ").append(sbText).append("\n");
                sbHex.setLength(0);
                sbText.setLength(0);
                bytesCounter=0;
            }else{
                bytesCounter++;
            }
        }

        //if still got content
        if(bytesCounter!=0){
            //add spaces more formatting purpose only
            for(; bytesCounter<16; bytesCounter++){
                //1 character 3 spaces
                sbHex.append("   ");
            }
            sbResult.append(sbHex).append("      ").append(sbText).append("\n");
        }

        out.print(sbResult);
        is.close();
    }
    public static String convertToHex( File file) throws IOException {
        InputStream is = new FileInputStream(file);

        int bytesCounter =0;
        int value = 0;
        StringBuilder sbHex = new StringBuilder();
        StringBuilder sbText = new StringBuilder();
        StringBuilder sbResult = new StringBuilder();

        while ((value = is.read()) != -1) {
            //convert to hex value with "X" formatter
            sbHex.append(String.format("%02X ", value));

            //If the chracater is not convertable, just print a dot symbol "."
            if (!Character.isISOControl(value)) {
                sbText.append((char)value);
            }else {
                sbText.append(".");
            }

            //if 16 bytes are read, reset the counter,
            //clear the StringBuilder for formatting purpose only.
            if(bytesCounter==15){
                sbResult.append(sbHex).append("      ").append(sbText).append("\n");
                sbHex.setLength(0);
                sbText.setLength(0);
                bytesCounter=0;
            }else{
                bytesCounter++;
            }
        }

        //if still got content
        if(bytesCounter!=0){
            //add spaces more formatting purpose only
            for(; bytesCounter<16; bytesCounter++){
                //1 character 3 spaces
                sbHex.append("   ");
            }
            sbResult.append(sbHex).append("      ").append(sbText).append("\n");
        }

        is.close();
        return sbResult.toString().toString().replaceAll(" ","").replaceAll("\n","");
    }


    public String convertToHex() throws Exception{

        StringBuilder result = new StringBuilder();
        String gdsHex = Hex.encodeHexString(FileUtil.readBytes(new File("C:\\Users\\admin\\Desktop\\gds相关资料\\cantilever(product)(1).gds"))).toUpperCase();
//        String gdsHex = Hex.encodeHexString(FileUtil.readBytes(new File("F:\\developetools\\L-Edit 11.1\\yunfang.gds"))).toUpperCase();
        int value=0;

        //拿到分割好的模块字节，根据字节解析内容
        GdsParameter.gdsParameterInit();
//        System.out.println(GdsParameter.gdsParameterMap.get("0002"));

        GdsFile gdsFile = new GdsFile();
        GdsStructure gdsStructure = new GdsStructure();
        GdsGraph gdsGraph = new GdsGraph();
        //将所有模块对应的字节数全部分组
        while (value<gdsHex.length()){
            String moldName =gdsHex.substring(value+4,value+8);
            String startSize =gdsHex.substring(value,value+4);
            int endSize = value+(new BigInteger(startSize, 16).intValue())*2;
            String middle = gdsHex.substring(value,endSize);
            if ("".equals(middle)){
                break;
            }
            System.out.println(GdsParameter.gdsParameterMap.get(moldName));
            result.append("\n").append(GdsParameter.gdsParameterMap.get(moldName)).append("\n");
            if (GdsParameter.BGNSTR.equals(moldName)){
                gdsStructure = new GdsStructure();
            }
            System.out.println(gdsParse.hexConvertToTxt(middle,gdsFile,gdsStructure,gdsGraph));
            result.append(gdsParse.hexConvertToTxt(middle,gdsFile,gdsStructure,gdsGraph)).append("\n");

            if (GdsParameter.ENDNET.equals(moldName)){
                gdsGraph= new GdsGraph();
            }

            System.out.println("元数据："+middle);
            result.append("元数据："+middle).append("\n");
            value=endSize;
        }

        return result.toString();
    }

    public String convertToHex(byte[] file) throws Exception{

        StringBuilder result = new StringBuilder();
        String gdsHex = Hex.encodeHexString(file).toUpperCase();
//        String gdsHex = Hex.encodeHexString(FileUtil.readBytes(new File("F:\\developetools\\L-Edit 11.1\\yunfang.gds"))).toUpperCase();
        int value=0;

        //拿到分割好的模块字节，根据字节解析内容
        GdsParameter.gdsParameterInit();
//        System.out.println(GdsParameter.gdsParameterMap.get("0002"));

        GdsFile gdsFile = new GdsFile();
        GdsStructure gdsStructure = new GdsStructure();
        GdsGraph gdsGraph = new GdsGraph();
        //将所有模块对应的字节数全部分组
        while (value<gdsHex.length()){
            String moldName =gdsHex.substring(value+4,value+8);
            String startSize =gdsHex.substring(value,value+4);
            int endSize = value+(new BigInteger(startSize, 16).intValue())*2;
            String middle = gdsHex.substring(value,endSize);
            if ("".equals(middle)){
                break;
            }
            System.out.println(GdsParameter.gdsParameterMap.get(moldName));
            result.append("\n").append(GdsParameter.gdsParameterMap.get(moldName)).append("\n");
            if (GdsParameter.BGNSTR.equals(moldName)){
                gdsStructure = new GdsStructure();
            }
            GdsDTO gdsDTO = gdsParse.hexConvertToTxt(middle,gdsFile,gdsStructure,gdsGraph);
            gdsFile=gdsDTO.getGdsFile();
            gdsStructure=gdsDTO.getGdsStructure();
            gdsGraph = gdsDTO.getGdsGraph();
            System.out.println(gdsDTO.getResult());
            result.append(gdsDTO.getResult()).append("\n");

            if (GdsParameter.ENDNET.equals(moldName)){
                gdsGraph= new GdsGraph();
            }

            System.out.println("元数据："+middle);
            result.append("元数据："+middle).append("\n");
            value=endSize;
        }

        return result.toString();
    }

    public static void main(String[] args) throws Exception
    {
        //display output to console
//        convertToHex(System.out, new File("C:\\Users\\admin\\Desktop\\gds相关资料\\probe.gds"));

//        BigInteger bigInteger = new BigInteger(1, FileUtil.readBytes(new File("C:\\Users\\admin\\Desktop\\gds相关资料\\probe.gds")));
//        System.out.println(bigInteger.toString(16));
        //write the output into a file
//        convertToHex(new PrintStream("C:\\Users\\admin\\Desktop\\gds相关资料\\file.txt"), new File("C:\\Users\\admin\\Desktop\\gds相关资料\\probe.gds"));

        /*String gdsHex = Hex.encodeHexString(FileUtil.readBytes(new File("C:\\Users\\admin\\Desktop\\gds相关资料\\probe.gds")));
        String part =gdsHex.substring(4,8);
        System.out.println(part);
        System.out.println(gdsHex.length());*/

//        convertToHex();

//        FileUtil.writeBytes(convertToHex().getBytes(),"C:\\Users\\admin\\Desktop\\gds相关资料\\cantilever.txt");
    }
}

